package ldk.app.kotlinweibo.configs

import android.content.Context
import android.util.Log
import com.sina.weibo.sdk.auth.AccessTokenKeeper
import com.sina.weibo.sdk.auth.Oauth2AccessToken
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import ldk.app.kotlinweibo.apis.UsersAPI
import ldk.app.kotlinweibo.apis.beans.User
import ldk.util.logger.LLog
import retrofit2.Retrofit
import javax.inject.Inject
import javax.inject.Singleton

/**
 * A class for manager logged user info
 * Created by yunjiao on 2017/6/15.
 */
@Singleton
class Session @Inject constructor(context: Context) {
    private val TAG = "Session"

    private val mApplicationContext : Context = context.applicationContext
    private var mSinaAccessToken : Oauth2AccessToken? = AccessTokenKeeper.readAccessToken(mApplicationContext)
    private var mUser: User? = null

    var userInfoValid = false

    fun currentUser(retrofit: Retrofit): Observable<User>{
        if (userInfoValid && mUser != null){
            return Observable.just(mUser)
        }
        return refreshUserInfo(retrofit)
    }

    fun isLogin():Boolean{
        return mSinaAccessToken == null || mSinaAccessToken!!.isSessionValid
    }

    fun logoutInternal(){
        mSinaAccessToken = null
        AccessTokenKeeper.clear(mApplicationContext)

        mUser = null
    }

    fun loginInternal(sinaAccessToken: Oauth2AccessToken){
        mSinaAccessToken = sinaAccessToken
    }

    private fun refreshUserInfo(retrofit: Retrofit): Observable<User>{
        if (!isLogin()) return Observable.error(IllegalStateException("not login"))
        val userAPI = retrofit.create(UsersAPI::class.java)
        val result = userAPI.getMyUId()
                .subscribeOn(Schedulers.io())
                .concatMap{
                    val uid = it.uid!!.toLong()
                    LLog.v(TAG, "got uid is: $uid")
                    userAPI.showByUid(uid)
                }
                .share()
        result.subscribe(
                {
                    mUser = it
                    userInfoValid = true
                },
                { Log.e(TAG, "refreshUserInfo failed: $it", it) })
        return result
    }

    fun sinaAccessToken(): String{
        if (isLogin()){
            return mSinaAccessToken!!.token
        }
        throw IllegalStateException("not login state, please check isLogin()")
    }
}